<template>
  <div>
    <div>
      <el-upload class="flx-align-center" :file-list="fileList" :multiple="multiple" :limit="limit" :disabled="disabled"
        :accept="fileType" :show-file-list="false" :http-request="handleHttpUpload" :before-upload="beforeUpload"
        :on-exceed="handleExceed">
        <slot name="upload-btn">
          <div class="upload-content">
            <el-button type="primary" :icon="UploadFilled" plain @click="handleClick">点击上传</el-button>
          </div>
        </slot>
      </el-upload>
      <!-- 提示 -->
      <div class="upload-tip" v-if="tipShow">
        <slot name="tip">{{ tipComputed }}</slot>
      </div>
    </div>
    <div class="upload-box">
      <slot></slot>
    </div>
  </div>
</template>

<script setup lang="ts" name="UploadBasics">
import { ref, computed } from 'vue'
import { UploadFilled } from '@element-plus/icons-vue'
import type { UploadUserFile, UploadRawFile, UploadRequestOptions } from 'element-plus'
import { ElNotification } from 'element-plus'
// import { uploadImg } from "@/api/modules/upload";
import { getFileType } from '@/utils/assetsFile'
import NewImg from '@/assets/images/new.jpg'

interface UploadFileProps {
  fileType: string
  fileSize: number // 允许上传文件的最大尺寸
  limit: number // 允许上传文件的最大数量
  tipShow: boolean // 是否显示提示
  multiple: boolean // 是否可以多选
  fileList: UploadUserFile[]
  disabled: boolean
  handleClick: () => void // 点击上传按钮自定义事件, 可在禁用时触发
}

const props = withDefaults(defineProps<Partial<UploadFileProps>>(), {
  fileType: '.pdf, .jpg, .png, .jpeg',
  fileSize: 10,
  tipShow: true,
  multiple: true,
  fileList: () => [],
  disabled: false,
})

// 提示
const tipComputed = computed(() => {
  const tip = props.fileType
    .replace(/\./g, '')
    .replace(/,/g, '、')
    .toUpperCase()
  return `支持${tip}格式，大小不得超过${props.fileSize}M`
})

// 文件上传前的钩子
const beforeUpload = (rawFile: UploadRawFile) => {
  // 判断文件类型, 不显示小数点
  const extension = getFileType(rawFile.name, 1)
  const fileType = props.fileType.replace(/\./g, '') // 若传入类型有小数点，替换
  const imgType = fileType.includes(extension)
  if (!imgType) {
    ElNotification({
      title: '温馨提示',
      message: '上传图片不符合所需的格式！',
      type: 'warning',
    })
    return false
  }
  // 判断大小
  if (rawFile.size / 1024 / 1024 > props.fileSize) {
    ElNotification({
      title: '温馨提示',
      message: `上传图片大小不能超过 ${props.fileSize}M！`,
      type: 'warning',
    })
    return false
  }
}

const handleExceed = () => {
  ElNotification({
    title: '温馨提示',
    message: `超出文件上传最大数量：${props.limit}！`,
    type: 'warning',
  })
  return false
}

// 上传文件请求
const uploadLatestFile = ref<UploadUserFile>() // 最近上传的文件
const uploadList = ref<UploadUserFile[]>([]) // 所有上传的文件列表

const handleHttpUpload = async (options: UploadRequestOptions) => {
  let formData = new FormData()
  formData.append('file', options.file)

  try {
    // 上传请求
    // const { data } = await uploadImg(formData);
    // TODO 更换真整的请求
    const data = { data: { name: options.file.name, url: NewImg } }

    uploadLatestFile.value = {
      name: data.data.name as string,
      url: data.data.url,
    }

    uploadList.value = [
      ...uploadList.value,
      {
        name: data.data.name as string,
        url: data.data.url,
      },
    ]

    emits('upload-success', {
      uploadLatestFile: uploadLatestFile.value,
      uploadList: uploadList.value,
    })
  } catch (error) {
    options.onError(error as any)
  }
}

const emits = defineEmits(['upload-success'])

defineExpose({
  uploadList,
  uploadLatestFile,
})
</script>

<style lang="scss" scoped>
// 上传按钮区
.upload-content {
  display: flex;
  flex-direction: column;
}

// 上传文件显示容器
.upload-box {
  max-height: 400px;

  // margin-top: 10px;
  overflow: auto;
}

// 提示
.upload-tip {
  display: flex;
  align-items: center;
  font-size: 12px;
  line-height: 32px;
  color: var(--el-label-color-regular);
}
</style>
